#ifndef UTILS_HPP_INCLUDED
#define UTILS_HPP_INCLUDED

#include <stdio.h>
#include <stdlib.h>
#include "Rtree.hpp"

#define MAIOR(a,b) (a>b?a:b);
#define MENOR(a,b) (a<b?a:b);
#define SQR(a) (a*a);

///Classes definidas em Rtree.hpp
class Entrada;
class EntradaInterna;
class EntradaFolha;

class Ponto{
	private:
		int dim;
		int indice;
		float *coordenadas;
		static int indiceCont;
		Ponto(int dim, int indice);

	public:
		Ponto(int dim);
		~Ponto();
		int getDim();
		int getIndice();
		void setCoord(int indiceEixo, float valor);
		float getCoord(int indiceEixo);
		void print();
		void gera();
		void float2ponto(float p[], int tam);
		void copia(Ponto **destino);
};

class BoundingBox{
    private:
        int dim; ///Dimensão do bb = número de eixos
		float *eixoMin; ///Valores mínimos dos eixos
		float *eixoMax; ///Valores máximos dos eixos
	public:
		BoundingBox(int dim);
		~BoundingBox();
		int getDim();
		void setEixoMin(int indiceEixo, float valor);
		void setEixoMax(int indiceEixo, float valor);
		float getEixoMin(int indiceEixo);
		float getEixoMax(int indiceEixo);
		void copia(BoundingBox *destino);
		void print();

		void insere(Ponto *ponto); ///Insere ponto e ajusta limites da bb
		float area(); ///Calcula 'area' (R²) da bb. R³ -> volume ...
		float sobreposicao(BoundingBox *bb); ///Calcula área de sobreposição das bb de mesma dimensão
        void ajustaFolha(EntradaFolha **ent, int tamanho); ///Ajusta bb a um conjunto de entradas folhas
        void ajustaInterna(EntradaInterna **ent, int tamanho); ///Ajusta bb a um conjunto de entradas internas

};

///Ordena vetor e armazena os indices antigos em pos. Bubblesort
void ordenacao(float vetor[], int pos[], int tamanho);

///Retorna os k maiores valores de vetor. maiores[] contém os indices. Bubblesort parcial
void kMaiores(float vetor[], int tamanho, int k, int maiores[]);

#endif // UTILS_HPP_INCLUDED
